package org.hackystat.ui.telemetryviewer.client;

import java.util.Map;

import org.hackystat.ui.telemetryviewer.client.common.BasicConveyor;
import org.hackystat.ui.telemetryviewer.client.common.PropertyKeys;
import org.hackystat.ui.telemetryviewer.client.common.Session;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * A widget to view realtime Hackystat sensor data.
 * @author David J. Nickles
 */
public class CompositeWidget extends Composite implements EntryPoint {

  /** {@literal} RIGHTCHARTOFFSET extended offset from the right for the chart pane. */
  private static final int WIDGETRIGHTOFFSET = 34;
  /** {@literal} HOST_ELEMENT_ID the DOM element ID. */
  public static final String HOST_ELEMENT_ID = "hostpanel";
  /** {@literal} USER_ELEMENT_ID the DOM element ID. */
  public static final String USER_ELEMENT_ID = "userpanel";
  /** {@literal} CHART_SELECT_ELEMENT_ID the DOM element ID. */
  public static final String CHART_SELECT_ELEMENT_ID = "chartselectpanel";
  /** {@literal} CHART_HEADER_ELEMENT_ID the DOM element ID. */
  public static final String CHART_HEADER_ELEMENT_ID = "chartheaderpanel";
  /** {@literal} CHART_ELEMENT_ID the DOM element ID. */
  public static final String CHART_ELEMENT_ID = "chartdisplaypanel";
  /** {@literal} CHART_SETTINGS_ELEMENT_ID the DOM element ID. */
  public static final String CHART_SETTINGS_ELEMENT_ID = "chartsettingspanel";
  /** {@literal} OPEN_ELEMENT the DOM element ID. */
  public static final String OPEN_ELEMENT = "<div id=\"";
  /** {@literal} CLOSE_ELEMENT the DOM element ID. */
  public static final String CLOSE_ELEMENT = "\"></div>";
  
  /* Widget UI elements */
  private HostStatusPanel hostPanel;
  private VerticalPanel mainPanel;
  private Session session;

  /**
   * This is the entry point method.
   */
  public void onModuleLoad() {
    rpcReadManifest();
    initLayout();
  }
  
  /**
   * This method creates and initializes the small gadget settings panel.
   */
  private void initLayout() {
    this.session = new Session();
    this.mainPanel = new VerticalPanel();
    this.mainPanel.add(new HTML(OPEN_ELEMENT + HOST_ELEMENT_ID + CLOSE_ELEMENT));
    this.mainPanel.add(new HTML(OPEN_ELEMENT + CHART_SELECT_ELEMENT_ID + CLOSE_ELEMENT));
    this.mainPanel.add(new HTML(OPEN_ELEMENT + CHART_SETTINGS_ELEMENT_ID + CLOSE_ELEMENT));
    this.mainPanel.add(new HTML(OPEN_ELEMENT + CHART_HEADER_ELEMENT_ID + CLOSE_ELEMENT));
    this.mainPanel.add(new HTML(OPEN_ELEMENT + CHART_ELEMENT_ID + CLOSE_ELEMENT));
    initWidget(this.mainPanel);
    RootPanel.get("widget").add(this);
    (this.hostPanel = new HostStatusPanel(this.session)).init();
    RootPanel.get("help").setVisible(false);
  }
  
  /**
   * This method displays the passed version in the UI.
   * @param conveyor carrying attributes from the manifest file.
   */
  public void digestManifest(BasicConveyor conveyor) {
    if (Boolean.TRUE.toString().equals(conveyor.getStatus())) {
      Map manifestMap = conveyor.getMap();
      Window.setTitle((String)manifestMap.get(PropertyKeys.TITLE));
      RootPanel.get("version").add(new HTML("<b>v." + (String)manifestMap.get(PropertyKeys.VERSION)
        + "</b>"));
      RootPanel title = RootPanel.get("text");
      if (title != null) {
        title.add(new HTML("<div style=\"color: white; font-weight: strong;\">" 
          + (String)manifestMap.get(PropertyKeys.TITLE) + "</div>"));
      }
    }
    else {
      showAlert(conveyor.getStatus());
    }
  }
  
  /**
   * Check with the servlet to see if the host is valid.
   */
  private void rpcReadManifest() {
    RPCServiceFactory.getInstance().getService().getManifest(new AsyncCallback() {
      public void onSuccess(Object result) {
        digestManifest((BasicConveyor) result);
      }
  
      public void onFailure(Throwable caught) {
        if (caught instanceof com.google.gwt.user.client.rpc.InvocationException) {
          log(RPCServiceFactory.PRCERRORNAME, "Cannot invoke version request on servlet.");
        } 
        else {
          log(RPCServiceFactory.PRCERRORNAME, caught.toString());
        }
      }
    });
  }
  
  /**
   * Log this message in the reader display.
   * @param header the message header or subject
   * @param body the message body
   */
  public static void log(String header, String body) {
    Window.alert(header + " : " + body);
  }
  
  /**
   * Display the message about waiting.
   */
  public static void clearWaiting() {
    RootPanel.get(CompositeWidget.CHART_ELEMENT_ID).clear();
  }
  
  /**
   * Display the message about waiting.
   * @param message to display.
   */
  public static void showWaiting(String message) {
    RootPanel.get(CompositeWidget.CHART_ELEMENT_ID).clear();
    WaitPanel waitPanel = new WaitPanel(message);
    RootPanel.get(CompositeWidget.CHART_ELEMENT_ID).add(waitPanel);
    waitPanel.setWidth(Integer.toString(Window.getClientWidth() - WIDGETRIGHTOFFSET) 
      + Styles.PIXELSUFFIX);
  }
  
  /**
   * Display the message about waiting.
   * @param message to display.
   */
  public static void showAlert(String message) {
    RootPanel.get(CompositeWidget.CHART_ELEMENT_ID).clear();
    AlertPanel alertPanel = new AlertPanel(message);
    RootPanel.get(CompositeWidget.CHART_ELEMENT_ID).add(alertPanel);
    alertPanel.setWidth(Integer.toString(Window.getClientWidth() - WIDGETRIGHTOFFSET) 
      + Styles.PIXELSUFFIX);
  }
}


